package com.rbac.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.rbac.common.RedisKey;
import com.rbac.dto.UserQueryDTO;
import com.rbac.entity.SysPermission;
import com.rbac.entity.SysUser;
import com.rbac.mapper.UserMapper;
import com.rbac.service.RedisService;
import com.rbac.service.UserService;
import com.rbac.vo.UserVO;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private RedisService redisService;
    
    @Override
    public SysUser getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }
    
    @Override
    public SysUser getUserById(Long id) {
        return userMapper.selectById(id);
    }
    
    @Override
    public PageInfo<UserVO> getUserList(UserQueryDTO queryDTO) {
        PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize());
        
        List<UserVO> userList = userMapper.selectUserList(queryDTO);
        
        // 为每个用户设置角色名称
        for (UserVO userVO : userList) {
            List<String> roleNames = userMapper.selectRoleNamesByUserId(userVO.getId());
            userVO.setRoleNames(roleNames);
        }
        
        return new PageInfo<>(userList);
    }
    
    @Override
    @Transactional
    public boolean addUser(SysUser user) {
        // 检查用户名是否已存在
        SysUser existUser = userMapper.selectByUsername(user.getUsername());
        if (existUser != null) {
            return false;
        }
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setStatus(1); // 默认启用
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        // 设置默认值
        if (user.getEmail() == null) user.setEmail("");
        if (user.getPhone() == null) user.setPhone("");
        if (user.getRealName() == null) user.setRealName("");
        if (user.getAvatar() == null) user.setAvatar("");
        if (user.getRemark() == null) user.setRemark("");
        
        return userMapper.insert(user) > 0;
    }
    
    @Override
    @Transactional
    public boolean updateUser(SysUser user) {
        user.setUpdateTime(LocalDateTime.now());
        return userMapper.update(user) > 0;
    }
    
    @Override
    @Transactional
    public boolean deleteUser(Long id) {
        return userMapper.deleteById(id) > 0;
    }
    
    @Override
    @Transactional
    public boolean updateUserStatus(Long id, Integer status) {
        SysUser user = new SysUser();
        user.setId(id);
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());
        return userMapper.update(user) > 0;
    }
    
    @Override
    public List<Long> getRoleIdsByUserId(Long userId) {
        return userMapper.selectRoleIdsByUserId(userId);
    }
    
    @Override
    public List<String> getRoleNamesByUserId(Long userId) {
        return userMapper.selectRoleNamesByUserId(userId);
    }
    
    @Override
    @Transactional
    public boolean assignRoles(Long userId, List<Long> roleIds) {
        // 先删除用户原有角色
        userMapper.deleteUserRolesByUserId(userId);
        
        // 如果没有分配角色，直接返回成功
        if (roleIds == null || roleIds.isEmpty()) {
            // 清理缓存
            SysUser user = userMapper.selectById(userId);
            if (user != null) {
                redisService.delete(RedisKey.USER_PERMISSIONS, user.getUsername());
                redisService.delete(RedisKey.USER_MENUS, String.valueOf(userId));
                redisService.delete(RedisKey.USER_ROLES, String.valueOf(userId));
            }
            return true;
        }
        
        // 分配新角色
        boolean ok = userMapper.insertUserRoles(userId, roleIds) > 0;
        // 清理缓存
        SysUser user = userMapper.selectById(userId);
        if (user != null) {
            redisService.delete(RedisKey.USER_PERMISSIONS, user.getUsername());
            redisService.delete(RedisKey.USER_MENUS, String.valueOf(userId));
            redisService.delete(RedisKey.USER_ROLES, String.valueOf(userId));
        }
        return ok;
    }
    
    @Override
    public List<String> getUserPermissions() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return Collections.emptyList();
        }
        
        String username = authentication.getName();
        // 先查缓存
        String cached = redisService.getString(RedisKey.USER_PERMISSIONS, username);
        if (cached != null && !cached.trim().isEmpty()) {
            return Arrays.asList(cached.split(","));
        }
        
        List<String> permissions = userMapper.selectUserPermissions(username);
        if (permissions == null) permissions = Collections.emptyList();
        // 回填缓存（只有非空权限才缓存）
        if (!permissions.isEmpty()) {
            String joined = String.join(",", permissions);
            redisService.setString(RedisKey.USER_PERMISSIONS, joined, null, username);
        }
        return permissions;
    }

    // 新增：强制指定用户名的权限获取方法
    public List<String> getUserPermissionsByUsername(String username) {
        if (username == null || username.trim().isEmpty()) {
            return null;
        }
        String cached = redisService.getString(RedisKey.USER_PERMISSIONS, username);
        if (cached != null) {
            return Arrays.asList(cached.split(","));
        }
        List<String> permissions = userMapper.selectUserPermissions(username);
        if (permissions == null) permissions = Collections.emptyList();
        redisService.setString(RedisKey.USER_PERMISSIONS, String.join(",", permissions), null, username);
        return permissions;
    }
    
    @Override
    public List<SysPermission> getUserMenus() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null;
        }
        
        String username = authentication.getName();
        SysUser user = userMapper.selectByUsername(username);
        if (user == null) return Collections.emptyList();
        List<SysPermission> cached = redisService.getJson(
            RedisKey.USER_MENUS,
            new TypeReference<List<SysPermission>>() {},
            String.valueOf(user.getId())
        );
        if (cached != null) return cached;
        List<SysPermission> menus = userMapper.selectUserMenus(username);
        redisService.setJson(RedisKey.USER_MENUS, menus, null, String.valueOf(user.getId()));
        return menus;
    }
    
    @Override
    public Map<String, Object> getUserInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null;
        }
        
        String username = authentication.getName();
        SysUser user = userMapper.selectByUsername(username);
        
        if (user == null) {
            return null;
        }
        
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("user", user);
        userInfo.put("permissions", getUserPermissions());
        userInfo.put("menus", getUserMenus());
        
        return userInfo;
    }
    
    @Override
    public void logout(String username) {
        // 用户登出处理逻辑（可记录日志等）
    }
} 